"""Some classes to use in multiple inheritance."""
#
#from PyQt4.QtCore import *
#import datetime
import misc
import threading
import time
#from system import infogetter
#from system import threads
#from agent import recorder
#from system import threads
#from system import tradezone
#import timedata
#import misc.quoteperiod as qp
#
#_INITIAL = 999
#_INIT_IG = 1000
#_INIT_RN1 = 1001
#_INIT_STARTRECORDER = 1002
#_INIT_UPDATEALLNAMES = 1003
#_INIT_RTS = 1004
#_WATCH = 2000



class Sleeper(object):
    def Sleep(self, t):
        """Sleeps with log."""
        tic = time.time()
        #self.logger.info("( _ v _ ) --- zzzzzzzzzzz (%g seconds)..." % t)
        dummy_event = threading.Event()
        dummy_event.wait(timeout=t)
        #self.logger.info("o< O v O >o ---(slept %.1g seconds)" % (time.time()-tic))


class Stocker(object):
    """Base for classes that manipulate a list of stocks.
    
    Two lists are maintained:
        - names1 comes from a stockset, whereas
        - names2 is dynamic.
    """

    
    ## Internal states
    # Stockset identifier. Either id or name will work
    _stocksets = None
    # stock names from stockset. Don't touch this (automatically maintained
    # from whichever is in _stocksets).
    _names1 = set([])
    # custom stock names
    _names2 = set([])
    # Generally, _names1 UNION _names2. Note that it is a list, not a set
    _allNames = []
    # Maching _allNames, but just the symbols
    _allSymbols = []

    ############################################################################
    ## Interface

    def SetStocksets(self, stocksets):
        if not isinstance(stocksets, (list, tuple)):
            stocksets = [stocksets]
        self._stocksets = stocksets
        self._UpdateAllNames()

    def SetNames2(self, names):
        """Sets _names2 and updates _allNames.
        
        This is called named2 because names1 comes from a stockset. """
        self._names2 = set(names)
        self._UpdateAllNames()
        
    def _OnUpdateAllNames(self):
        """Reimplement to do something whenever allNames is updated."""
        pass
        
    ############################################################################

    def _UpdateAllNames(self):
        """Called when SetStocksets() or SetNames2() is called. Inheritable.
        
        Shouldn't be inherited, inherit _OnUpdateAllNames() instead."""
        self._s_UpdateAllNames()
        self._OnUpdateAllNames()
    
    def _s_UpdateAllNames(self):
        """Does the set work."""
        self.__ReadNames1()
        self._allNames = list(self._names1.union(self._names2))
        self._allNames.sort()
        self._allSymbols = [misc.Name2Symbol(x) for x in self._allNames]
        
    def __ReadNames1(self):
        """Reads stock names from the Stockset."""
        x = self._stocksets
        self._names1 = set([]) if misc.isempty(x) else self.ReadStocksetsNames(x)

    def ReadStocksetsNames(self, stocksets):
        """Reads all stock names from a given stockset."""
        r = set([])
        for stockset in stocksets:
            names = na.vala.db.stockset_GetNamesByKey(stockset)
            if not names:
                # TODO: This is bad design, assumes the descendant will have a
                # logger.
                # TODO: I should create a base class with a stupid default logger
                self.logger.warning("Stockset \"%s\" has no items" % (stockset))
            else:
                r = r.union(set(names))
        return r


class StockerEx(Stocker):
    """Class created to be inherited by rtclasses.RealtimeManager.
    
    Extends Stocker with an additional expanded set called _allNamesEx
    
    So:
        _allNames: original, _names1 UNION _names2
        _moreNames: _moreNames1 UNION _moreNames2
        _allNamesEx: _allNames UNION _moreNames
    """

    ## Internal states
    # More stocksets to extend _allNames
    _moreStocksets = None
    # More names1 (corresponding to _moreStocksets)
    _moreNames1 = set([])
    # More names2 to extend _allNames
    _moreNames2 = set([])
    # _moreNames1 UNION _moreNames2. Note that it is a list, not a set
    _moreNames = []
    # Maching _moreNamesEx, but just the symbols
    _moreSymbolsEx = []
    # _allNames UNION _moreNames
    _allNamesEx = []
    # Maching _allNamesEx, but just the symbols
    _allSymbolsEx = []

    ############################################################################
    ## Interface

    def SetMoreStocksets(self, stocksets):
        if not isinstance(stocksets, (list, tuple)):
            stocksets = [stocksets]
        self._moreStocksets = stocksets
        self._UpdateMoreNames()

    def SetMoreNames2(self, names):
        """Sets _moreNames2 and updates _allNames and _allNamesEx."""
        self._moreNames2 = set(names)
        self._UpdateMoreNames()
        
    def SetNamess2(self, names2, moreNames2):
        """This was made so both can be set without calling _On*() twice.
        
        This is done without calling _UpdateAllNames()"""
        self._names2 = set(names2)
        self._moreNames2 = set(moreNames2)
        self._s_UpdateAllNames()
        self._s_UpdateMoreNames()
        self._s_UpdateAllNamesEx()
        self._OnUpdateAllNames()
        self._OnUpdateAllNamesEx()
        
    def _OnUpdateAllNamesEx(self):
        """Reimplement to do something whenever moreNamesEx is updated."""
        pass
    
    
    ############################################################################
    
    def _UpdateAllNames(self):
        """"Shouldn't be inherited, inherit _OnUpdateAllNames() instead."""
        Stocker._UpdateAllNames(self)
        self._UpdateAllNamesEx()
    
    def _UpdateMoreNames(self):
        """Called whenever SetMore*() is called.
        
        Shouldn't be inherited."""
        self._s_UpdateMoreNames()
        self._UpdateAllNamesEx()
        
    def _s_UpdateMoreNames(self):
        """Does the set work."""
        self.__ReadMoreNames1()
        self._moreNames = list(self._moreNames1.union(self._moreNames2))
        self._moreNames.sort()
        self._moreSymbols = [misc.Name2Symbol(x) for x in self._moreNames]
    
    def _UpdateAllNamesEx(self):
        """Called from _UpdateAllNames() or _UpdateMoreNames().
        
        This can be inherited but don't forget to call the ancestor."""
        self._s_UpdateAllNamesEx()
        self._OnUpdateAllNamesEx()
        
    def _s_UpdateAllNamesEx(self):
        self._allNamesEx = list(set(self._allNames).union(self._moreNames))
        self._allNamesEx.sort()
        self._allSymbolsEx = [misc.Name2Symbol(x) for x in self._allNamesEx]
        
    def __ReadMoreNames1(self):
        """Reads stock names corresponding to _moreStocksets."""
        x = self._moreStocksets
        self._names1 = set([]) if misc.isempty(x) else self.ReadStocksetsNames(x)


################################################################################
import system.navalasystem as na
